//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

#include <string.h>
#include <stdio.h>
#ifdef VS2005_COMPILER
  #pragma warning (disable : 4996)
#endif

#include "../Config.h"
#include "Image.h"

#include "TargaTexture.h"
#include "PngTexture.h"


//-----------------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------------
CImage::CImage() {

  m_nWidth = 0;
  m_nHeight = 0;
  m_pvImage = NULL;
  m_nBPP = 0;
  m_nColorChannels = 0;
}


//-----------------------------------------------------------------------------
// destructor
//-----------------------------------------------------------------------------
CImage::~CImage() {

  Init();
}


//-----------------------------------------------------------------------------
// inicializa a classe
//-----------------------------------------------------------------------------
bool CImage::Init() {

  if (m_pvImage) {

    delete[] ((unsigned char *)m_pvImage);
    m_pvImage = NULL;
  }

  m_nWidth = 0;
  m_nHeight = 0;
  m_nBPP = 0;
  m_nColorChannels = 0;

  return true;
}


//-----------------------------------------------------------------------------
// carrega um arquivo do disco
//-----------------------------------------------------------------------------
bool CImage::Load(const char *pszFilename) {

  // aux vars
  const char *pszAux;

  pszAux = strrchr(pszFilename, '.');

  if (strcmp(pszAux + 1, "png") == 0)
    return LoadPNG(pszFilename);
  else if (strcmp(pszAux + 1, "tga") == 0)
    return LoadTarga(pszFilename);

  // unknown extension
  cerr << "ERROR: unknow file extension: " << pszFilename << endl;
  return false;
}


//-----------------------------------------------------------------------------
// load a targa file
//-----------------------------------------------------------------------------
bool CImage::LoadTarga(const char *pszFilename) {

  //aux vars
  TargaTexture oTargaTexture;

  if (!oTargaTexture.load(pszFilename))
    return false;

  m_nWidth = oTargaTexture.width;
  m_nHeight = oTargaTexture.height;
  m_nBPP = oTargaTexture.bpp;
  m_nColorChannels = oTargaTexture.bytesPerPixel;
  if (m_nColorChannels > 4) {

    cerr << "ERROR: only byte images supported!" << endl;
    return false;
  }

  if (oTargaTexture.imageSize != m_nWidth * m_nHeight * m_nColorChannels) {

    cerr << "ERROR: loaded image size is different of the expected!" << endl;
    return false;
  }

  if (m_pvImage) {

    delete[] m_pvImage;
    m_pvImage = NULL;
  }
  m_pvImage = (void *)(new unsigned char[m_nWidth * m_nHeight * m_nColorChannels]);

  memcpy(m_pvImage, oTargaTexture.imageData, oTargaTexture.imageSize);

  return true;
}


//-----------------------------------------------------------------------------
// load a png file
//-----------------------------------------------------------------------------
bool CImage::LoadPNG(const char *pszFilename) {

  //aux vars
  PngTexture oTexture;

  if (oTexture.load(pszFilename) != 0)
    return false;

  m_nWidth = oTexture.getWidth();
  m_nHeight = oTexture.getHeight();
  m_nColorChannels = oTexture.getChannels();
  m_nBPP = oTexture.getBPP();

  if (m_nBPP <= 0 || (m_nBPP != 8 * m_nColorChannels)) {

    cerr << "ERROR: not suported BPP!" << endl;
    return false;
  }

  if (m_pvImage) {

    delete[] m_pvImage;
    m_pvImage = NULL;
  }
  m_pvImage = (void *)(new unsigned char[m_nWidth * m_nHeight * m_nColorChannels]);

  oTexture.CopyToBuffer((unsigned char *)m_pvImage);

  return true;
}
